package com.neo.design.chain;

/**
 * 业务链封装中心标识<p/>
 * 在项目中如果有业务需要使用责任链进行代码拆分解耦，则首先需要实现该标识类<p/>
 * 例如：在项目中有一个审批流程需要用到责任链模式，则首先需要实现该接口，比如：{@link com.neo.design.chain.approve.ApproveContext}，
 * 然后在实现类中进行业务上下文的定义和组装<p/>
 * <p/>
 * 注意：尽量避免长链业务的存在，因为长链业务对性能会产生影响<p/>
 * 注意：尽量避免长链业务的存在，因为长链业务对性能会产生影响<p/>
 * 注意：尽量避免长链业务的存在，因为长链业务对性能会产生影响<p/>
 * 重要的事情说三遍，如果有长链业务（具体限制多少，根据自己项目的情况而定），请优化业务逻辑，或改用其他设计模式
 * <p/>
 * 需要注意的是，每个业务都需要继承实现自己的请求参数类{@link ChainRequest}和返回结果类{@link ChainResult}，
 * 在责任链管理中心{@link ChainContextManager}里，根据请求参数的类型会自动进行业务处理中心的匹配{@link ChainContext#match(ChainRequest)}
 * 然后进行业务处理
 *
 * @author Kevin
 */
public interface ChainContext<T extends ChainRequest, R extends ChainResult> {

    /**
     * 初始化业务上下文，实现该接口的时候，可以基于此方法进行业务组装，也可以自定义初始化方法<p/>
     * 这里不做强制要求，看自己的编码习惯而定，具体可参考{@link com.neo.design.chain.approve.ApproveContext#init()}
     */
    @SuppressWarnings("unused")
    default void init() {

    }

    /**
     * 处理业务请求
     *
     * @param request 业务请求参数 {@link ChainRequest}
     * @return 处理结果 {@link ChainResult}
     */
    R handleRequest(T request);

    /**
     * 判断当前业务上下文是否可以处理该请求<p/>
     * 每个业务中心都需要实现该方法，实现方式为根据请求参数类型判断是否符合本业务的处理<p/>
     * 比如:{@link com.neo.design.chain.approve.ApproveContext#match(ChainRequest)}
     * <p/>
     * 判断方式: {@code request instanceof ChainRequest}, 这里的ChainRequest每个业务根据自己的业务进行实现
     *
     * @param request 业务请求参数 {@link ChainRequest}
     * @return 业务是否匹配 {@code true}：匹配，{@code false}：不匹配
     */
    boolean match(ChainRequest request);
}
